package com.chukun.inventory.thread;


import com.chukun.inventory.request.InventoryRequest;
import com.chukun.inventory.request.ProductInventoryCacheRefreshRequest;
import com.chukun.inventory.request.ProductInventoryDBUpdateRequest;

import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 执行请求的工作线程
 */
public class InventoryRequestProcessorThread implements Callable<Boolean> {

    private BlockingQueue<InventoryRequest> queue;

    /**
     * k: 商品 id v：请求标志： true : 有更新请求
     */
    private Map<Integer, Boolean> flagMap = new ConcurrentHashMap<>();

    public InventoryRequestProcessorThread(BlockingQueue<InventoryRequest> queue) {
        this.queue = queue;
    }
    /**
     * 监控的内存队列
     * @return
     * @throws Exception
     */
    @Override
    public Boolean call() throws Exception {
        try {
            while (true) {
                // ArrayBlockingQueue
                // Blocking就是说明，如果队列满了，或者是空的，那么都会在执行操作的时候，阻塞住
                InventoryRequest request = queue.take();
                if (request.forceRfresh()) {
                    // 强制刷新缓存
                    request.process();
                    return Boolean.TRUE;
                }
                if (request instanceof ProductInventoryDBUpdateRequest) {
                    flagMap.put(request.getProductId(), true);
                } else if (request instanceof ProductInventoryCacheRefreshRequest) {
                    Boolean flag = flagMap.get(request.getProductId());
                    if (flag == null) {
                        flagMap.put(request.getProductId(), false);
                    }
                    // 已经有过读或写的请求 并且前面已经有一个写请求了
                    if (flag !=null && flag) {
                        flagMap.put(request.getProductId(), false);
                    } else if (flag !=null && !flag) {
                        continue;
                    }
                }
                // 执行这个request操作
                request.process();
            }
        }catch (Exception e){
             // log exception
        }
        return true;
    }
}
